package fr.bludwarf.skywarrior.global;

import java.util.HashMap;
import java.util.Set;

import fr.bludwarf.skywarrior.exceptions.ConstructionImpossibleException;
import fr.bludwarf.skywarrior.exceptions.EvenementInconnuOublieException;


/**
 * @param <E> type de l'entité sur laquelle on agit
 * @param <F> type de l'entité des fils
 * @param <EF> type de l'état des entité des fils
 * @since 4 nov. 2011
 */
public abstract class EtatPere<E extends EntiteMere<?>, F extends Entite, EF extends Etat<F>> extends Etat<E> {
	
	HashMap<F, EF> _etatsFils = new HashMap<F, EF>(); 

	public EtatPere(E entite, final EtatPere<?,?,?> etatPere) {
		super(entite, etatPere);
	}

	public EtatPere(EtatPere<E, F, EF> etat) throws Exception {
		super(etat);
		
		// Clone des fils
		final HashMap<F, EF> etatsFils = etat.getEtatsFils();
		for (final F fils : etatsFils.keySet())
		{
			final EF etatFils = etatsFils.get(fils);
			_etatsFils.put(fils, newEtatFils(etatFils, this));
		}
	}

	@SuppressWarnings("unchecked")
	protected void init() {
		// Init des états des fils
		for (F fils : ((Set<F>)_entite.getFils()))
		{
			_etatsFils.put(fils, etatInitialFils(fils));
		}
	}
	
	/**
	 * Ajoute un état dans les fils
	 * @param etat
	 */
	public void add(EF etat)
	{
		_etatsFils.put(etat.getEntite(), etat);
	}
	
	/**
	 * Ajoute un fils => on doit créer un nouvel état
	 * @param entite
	 */
	public void add(F fils)
	{
		_etatsFils.put(fils, etatInitialFils(fils));
	}

	protected abstract EF etatInitialFils(F fils);

	protected abstract EF newEtatFils(EF etatInitial, EtatPere<E, F, EF> etatPere) throws Exception;
	
	public HashMap<F, EF> getEtatsFils()
	{
		return _etatsFils;
	}
	
	@Override
	public void avancer(double temps) throws Exception {
		
		// avance des fils
		final HashMap<F, EF> etatsFils = getEtatsFils();
		for (final F fils : etatsFils.keySet())
		{
			final EF etatFils = etatsFils.get(fils);
			etatFils.avancer(temps);
		}
	}

}
